package leetcode.array;

/**
 * @author Cheng Jun
 * Description: 给你一根长度为 n 的绳子，请把绳子剪成整数长度的 m 段（m、n都是整数，n>1并且m>1），
 * 每段绳子的长度记为 k[0],k[1]...k[m - 1] 。请问 k[0]*k[1]*...*k[m - 1] 可能的最大乘积是多少？
 * 例如，当绳子的长度是8时，我们把它剪成长度分别为2、3、3的三段，此时得到的最大乘积是18。
 * <p>
 * 答案需要取模 1e9+7（1000000007），如计算初始结果为：1000000008，请返回 1。
 * 2 <= n , n <= 1000
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode-cn.com/problems/jian-sheng-zi-ii-lcof
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 * @version 1.0
 * @date 2022/1/27 15:28
 */
public class cuttingRope1 {

    // 这里有个细节，就是如果 i 被切割成 1 和 i-1，那么下次选择的时候，就不能用 res[i]，而是使用 i
    // 下面代码不能通过 LeetCode，具体解释如下：
    // https://leetcode-cn.com/problems/jian-sheng-zi-ii-lcof/solution/di-zi-fen-xi-shi-yong-dong-tai-gui-hua-q-jlr7/
    @Deprecated
    static public int cuttingRope(int n) {
        // res[i] 表示长度为i 的绳子最大的乘积
        int[] res = new int[n + 1];
        for (int i = 2; i <= n; i++) {
            for (int j = 1; j < i; j++) {
                res[i] = Math.max(res[i], Math.max((i - j) * res[j] % 1000000007, (i - j) * j % 1000000007));
            }
        }
        return res[n];
    }

    static public int cuttingRope1(int n) {
        if (n == 2) return 1;
        if (n == 3) return 2;
        long res = 1;
        while (n > 4) {
            res = res * 3 % 1000000007;
            n -= 3;
        }
        // n 等于4时，还有 n 最后为 1,2,3 时的情况
        return (int) (res * n % 1000000007);
    }
}
